package cn.hgj.config;

import cn.hgj.enums.OrderEvent;
import cn.hgj.enums.OrderStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.EnumSet;

@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderStatus, OrderEvent> {


//    @Bean
//    public StateMachine<OrderStatus, OrderEvent> stateMachine(StateMachineFactory<OrderStatus, OrderEvent> factory) {
//        return factory.getStateMachine();
//    }

    @Override
    public void configure(StateMachineStateConfigurer<OrderStatus, OrderEvent> states)
            throws Exception {

        states.withStates()
                .initial(OrderStatus.INITIALIZED)
                .states(EnumSet.allOf(OrderStatus.class));
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<OrderStatus, OrderEvent> config) throws Exception {
        config.withConfiguration()
                .autoStartup(true);
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderEvent> transitions)
            throws Exception {

        transitions
                .withExternal()
                .source(OrderStatus.INITIALIZED)
                .target(OrderStatus.PAY_PENDING)
                .event(OrderEvent.CREATE_ORDER)
                .and()
                .withExternal()
                .source(OrderStatus.PAY_PENDING)
                .target(OrderStatus.PAY_SUCCESS)
                .event(OrderEvent.PAY_SUCCESS)
                .and()
                .withExternal()
                .source(OrderStatus.PAY_SUCCESS)
                .target(OrderStatus.PROCESSING)
                .event(OrderEvent.START_PROCESSING)
                .and()
                .withExternal()
                .source(OrderStatus.PROCESSING)
                .target(OrderStatus.COMPLETED)
                .event(OrderEvent.COMPLETE)
                .and()
                .withExternal()
                .source(OrderStatus.PAY_PENDING)
                .target(OrderStatus.CANCELED)
                .event(OrderEvent.PAY_FAILED)
                .and()
                .withExternal()
                .source(OrderStatus.PAY_PENDING)
                .target(OrderStatus.CANCELED)
                .event(OrderEvent.SYSTEM_TIMEOUT)
                .and()
                .withExternal()
                .source(OrderStatus.PAY_PENDING)
                .target(OrderStatus.CANCELED)
                .event(OrderEvent.USER_CANCEL);
    }
}
